home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / mig / dist / parser.y < prev    next >
Encoding:
Text File  |  1991-08-29  |  14.9 KB  |  710 lines

  1. /* 
  2.  * Mach Operating System
  3.  * Copyright (c) 1991,1990 Carnegie Mellon University
  4.  * All Rights Reserved.
  5.  * 
  6.  * Permission to use, copy, modify and distribute this software and its
  7.  * documentation is hereby granted, provided that both the copyright
  8.  * notice and this permission notice appear in all copies of the
  9.  * software, derivative works or modified versions, and any portions
  10.  * thereof, and that both notices appear in supporting documentation.
  11.  * 
  12.  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS 
  13.  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
  14.  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
  15.  * 
  16.  * Carnegie Mellon requests users of this software to return to
  17.  * 
  18.  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
  19.  *  School of Computer Science
  20.  *  Carnegie Mellon University
  21.  *  Pittsburgh PA 15213-3890
  22.  * 
  23.  * any improvements or extensions that they make and grant Carnegie the
  24.  * rights to redistribute these changes.
  25.  */
  26. /*
  27.  * HISTORY
  28.  * $Log:    parser.y,v $
  29.  * Revision 2.5  91/08/28  11:17:06  jsb
  30.  *     Added ServerDemux.
  31.  *     [91/08/13            rpd]
  32.  * 
  33.  *     Removed Camelot, TrapRoutine support.
  34.  *     Removed obsolete translation and destructor specs.
  35.  *     Replaced MsgKind with MsgSeqno.
  36.  *     [91/08/12            rpd]
  37.  * 
  38.  * Revision 2.4  91/07/31  18:10:00  dbg
  39.  *     Allow 'dealloc[]' to mean user-specified deallocate flag.
  40.  * 
  41.  *     Added c_string.
  42.  *     [91/04/03            dbg]
  43.  * 
  44.  * Revision 2.3  91/02/05  17:55:12  mrt
  45.  *     Changed to new Mach copyright
  46.  *     [91/02/01  17:54:54  mrt]
  47.  * 
  48.  * Revision 2.2  90/06/02  15:05:11  rpd
  49.  *     Created for new IPC.
  50.  *     [90/03/26  21:12:20  rpd]
  51.  * 
  52.  * 07-Apr-89  Richard Draves (rpd) at Carnegie-Mellon University
  53.  *    Extensive revamping.  Added polymorphic arguments.
  54.  *    Allow multiple variable-sized inline arguments in messages.
  55.  *
  56.  * 17-Feb-87  Mary Thompson (mrt) at Carnegie Mellon
  57.  *    Simplied syntax for translation and destructor functions.
  58.  *    Also allowed any combination of these functions.
  59.  *
  60.  * 16-Nov-87  David Golub (dbg) at Carnegie-Mellon University
  61.  *    Added maximum-size notation for arrays.  Added destructor
  62.  *    for server-side.
  63.  *
  64.  * 27-May-87  Richard Draves (rpd) at Carnegie-Mellon University
  65.  *    Created.
  66.  */
  67.  
  68. %token    sySkip
  69. %token    syRoutine
  70. %token    sySimpleRoutine
  71. %token    sySimpleProcedure
  72. %token    syProcedure
  73. %token    syFunction
  74.  
  75. %token    sySubsystem
  76. %token    syKernelUser
  77. %token    syKernelServer
  78.  
  79. %token    syMsgOption
  80. %token    syMsgSeqno
  81. %token    syWaitTime
  82. %token    syNoWaitTime
  83. %token    syErrorProc
  84. %token    syServerPrefix
  85. %token    syUserPrefix
  86. %token    syServerDemux
  87. %token    syRCSId
  88.  
  89. %token    syImport
  90. %token    syUImport
  91. %token    sySImport
  92.  
  93. %token    syIn
  94. %token    syOut
  95. %token    syInOut
  96. %token    syRequestPort
  97. %token    syReplyPort
  98. %token    sySReplyPort
  99. %token    syUReplyPort
  100.  
  101. %token    syType
  102. %token    syArray
  103. %token    syStruct
  104. %token    syOf
  105.  
  106. %token    syInTran
  107. %token    syOutTran
  108. %token    syDestructor
  109. %token    syCType
  110. %token    syCUserType
  111. %token    syCServerType
  112.  
  113. %token    syCString
  114.  
  115. %token    syColon
  116. %token    sySemi
  117. %token    syComma
  118. %token    syPlus
  119. %token    syMinus
  120. %token    syStar
  121. %token    syDiv
  122. %token    syLParen
  123. %token    syRParen
  124. %token    syEqual
  125. %token    syCaret
  126. %token    syTilde
  127. %token    syLAngle
  128. %token    syRAngle
  129. %token    syLBrack
  130. %token    syRBrack
  131. %token    syBar
  132.  
  133. %token    syError            /* lex error */
  134.  
  135. %token    <number>    syNumber
  136. %token    <symtype>    sySymbolicType
  137. %token    <identifier>    syIdentifier
  138. %token    <string>    syString syQString
  139. %token    <string>    syFileName
  140. %token    <flag>        syIPCFlag
  141.  
  142. %left    syPlus,syMinus
  143. %left    syStar,syDiv
  144.  
  145.  
  146. %type    <statement_kind> ImportIndicant
  147. %type    <number> VarArrayHead ArrayHead StructHead IntExp
  148. %type    <type> NamedTypeSpec TransTypeSpec TypeSpec
  149. %type    <type> CStringSpec
  150. %type    <type> BasicTypeSpec PrevTypeSpec ArgumentType
  151. %type    <symtype> PrimIPCType IPCType
  152. %type    <routine> RoutineDecl Routine SimpleRoutine
  153. %type    <routine> Procedure SimpleProcedure Function
  154. %type    <direction> Direction
  155. %type    <argument> Argument Arguments ArgumentList
  156. %type    <flag> IPCFlags
  157.  
  158. %{
  159.  
  160. #include "lexxer.h"
  161. #include "string.h"
  162. #include "type.h"
  163. #include "routine.h"
  164. #include "statement.h"
  165. #include "global.h"
  166.  
  167. static char *import_name();
  168.  
  169. %}
  170.  
  171. %union
  172. {
  173.     u_int number;
  174.     identifier_t identifier;
  175.     string_t string;
  176.     statement_kind_t statement_kind;
  177.     ipc_type_t *type;
  178.     struct
  179.     {
  180.     u_int innumber;        /* msgt_name value, when sending */
  181.     string_t instr;
  182.     u_int outnumber;    /* msgt_name value, when receiving */
  183.     string_t outstr;
  184.     u_int size;        /* 0 means there is no default size */
  185.     } symtype;
  186.     routine_t *routine;
  187.     arg_kind_t direction;
  188.     argument_t *argument;
  189.     ipc_flags_t flag;
  190. }
  191.  
  192. %%
  193.  
  194. Statements        :    /* empty */
  195.             |    Statements Statement
  196.             ;
  197.  
  198. Statement        :    Subsystem sySemi
  199.             |    WaitTime sySemi
  200.             |    MsgOption sySemi
  201.             |    Error sySemi
  202.             |    ServerPrefix sySemi
  203.             |    UserPrefix sySemi
  204.             |    ServerDemux sySemi
  205.             |    TypeDecl sySemi
  206.             |    RoutineDecl sySemi
  207. {
  208.     register statement_t *st = stAlloc();
  209.  
  210.     st->stKind = skRoutine;
  211.     st->stRoutine = $1;
  212.     rtCheckRoutine($1);
  213.     if (BeVerbose)
  214.     rtPrintRoutine($1);
  215. }
  216.             |    sySkip sySemi
  217.                 { rtSkip(); }
  218.             |    Import sySemi
  219.             |    RCSDecl sySemi
  220.             |    sySemi
  221.             |    error sySemi
  222.                 { yyerrok; }
  223.             ;
  224.  
  225. Subsystem        :    SubsystemStart SubsystemMods
  226.                 SubsystemName SubsystemBase
  227. {
  228.     if (BeVerbose)
  229.     {
  230.     printf("Subsystem %s: base = %u%s%s\n\n",
  231.            SubsystemName, SubsystemBase,
  232.            IsKernelUser ? ", KernelUser" : "",
  233.            IsKernelServer ? ", KernelServer" : "");
  234.     }
  235. }
  236.             ;
  237.  
  238. SubsystemStart        :    sySubsystem
  239. {
  240.     if (SubsystemName != strNULL)
  241.     {
  242.     warn("previous Subsystem decl (of %s) will be ignored", SubsystemName);
  243.     IsKernelUser = FALSE;
  244.     IsKernelServer = FALSE;
  245.     strfree(SubsystemName);
  246.     }
  247. }
  248.             ;
  249.  
  250. SubsystemMods        :    /* empty */
  251.             |    SubsystemMods SubsystemMod
  252.             ;
  253.  
  254. SubsystemMod        :    syKernelUser
  255. {
  256.     if (IsKernelUser)
  257.     warn("duplicate KernelUser keyword");
  258.     IsKernelUser = TRUE;
  259. }
  260.             |    syKernelServer
  261. {
  262.     if (IsKernelServer)
  263.     warn("duplicate KernelServer keyword");
  264.     IsKernelServer = TRUE;
  265. }
  266.             ;
  267.  
  268. SubsystemName        :    syIdentifier    { SubsystemName = $1; }
  269.             ;
  270.  
  271. SubsystemBase        :    syNumber    { SubsystemBase = $1; }
  272.             ;
  273.  
  274. MsgOption        :    LookString syMsgOption syString
  275. {
  276.     if (streql($3, "MACH_MSG_OPTION_NONE"))
  277.     {
  278.     MsgOption = strNULL;
  279.     if (BeVerbose)
  280.         printf("MsgOption: canceled\n\n");
  281.     }
  282.     else
  283.     {
  284.     MsgOption = $3;
  285.     if (BeVerbose)
  286.         printf("MsgOption %s\n\n",$3);
  287.     }
  288. }
  289.             ;
  290.  
  291. WaitTime        :    LookString syWaitTime syString
  292. {
  293.     WaitTime = $3;
  294.     if (BeVerbose)
  295.     printf("WaitTime %s\n\n", WaitTime);
  296. }
  297.             |    syNoWaitTime
  298. {
  299.     WaitTime = strNULL;
  300.     if (BeVerbose)
  301.     printf("NoWaitTime\n\n");
  302. }
  303.             ;
  304.  
  305. Error            :    syErrorProc syIdentifier
  306. {
  307.     ErrorProc = $2;
  308.     if (BeVerbose)
  309.     printf("ErrorProc %s\n\n", ErrorProc);
  310. }
  311.             ;
  312.  
  313. ServerPrefix        :    syServerPrefix syIdentifier
  314. {
  315.     ServerPrefix = $2;
  316.     if (BeVerbose)
  317.     printf("ServerPrefix %s\n\n", ServerPrefix);
  318. }
  319.             ;
  320.  
  321. UserPrefix        :    syUserPrefix syIdentifier
  322. {
  323.     UserPrefix = $2;
  324.     if (BeVerbose)
  325.     printf("UserPrefix %s\n\n", UserPrefix);
  326. }
  327.             ;
  328.  
  329. ServerDemux        :    syServerDemux syIdentifier
  330. {
  331.     ServerDemux = $2;
  332.     if (BeVerbose)
  333.     printf("ServerDemux %s\n\n", ServerDemux);
  334. }
  335.             ;
  336.  
  337. Import            :    LookFileName ImportIndicant syFileName
  338. {
  339.     register statement_t *st = stAlloc();
  340.     st->stKind = $2;
  341.     st->stFileName = $3;
  342.  
  343.     if (BeVerbose)
  344.     printf("%s %s\n\n", import_name($2), $3);
  345. }
  346.             ;
  347.  
  348. ImportIndicant        :    syImport    { $$ = skImport; }
  349.             |    syUImport    { $$ = skUImport; }
  350.             |    sySImport    { $$ = skSImport; }
  351.             ;
  352.  
  353. RCSDecl            :    LookQString syRCSId syQString
  354. {
  355.     if (RCSId != strNULL)
  356.     warn("previous RCS decl will be ignored");
  357.     if (BeVerbose)
  358.     printf("RCSId %s\n\n", $3);
  359.     RCSId = $3;
  360. }
  361.             ;
  362.  
  363. TypeDecl        :    syType NamedTypeSpec
  364. {
  365.     register identifier_t name = $2->itName;
  366.  
  367.     if (itLookUp(name) != itNULL)
  368.     warn("overriding previous definition of %s", name);
  369.     itInsert(name, $2);
  370. }
  371.             ;
  372.  
  373. NamedTypeSpec        :    syIdentifier syEqual TransTypeSpec
  374.                 { itTypeDecl($1, $$ = $3); }
  375.             ;
  376.  
  377. TransTypeSpec        :    TypeSpec
  378.                 { $$ = itResetType($1); }
  379.             |    TransTypeSpec syInTran syColon syIdentifier
  380.                 syIdentifier syLParen syIdentifier syRParen 
  381. {
  382.     $$ = $1;
  383.  
  384.     if (($$->itTransType != strNULL) && !streql($$->itTransType, $4))
  385.     warn("conflicting translation types (%s, %s)",
  386.          $$->itTransType, $4);
  387.     $$->itTransType = $4;
  388.  
  389.     if (($$->itInTrans != strNULL) && !streql($$->itInTrans, $5))
  390.     warn("conflicting in-translation functions (%s, %s)",
  391.          $$->itInTrans, $5);
  392.     $$->itInTrans = $5;
  393.  
  394.     if (($$->itServerType != strNULL) && !streql($$->itServerType, $7))
  395.     warn("conflicting server types (%s, %s)",
  396.          $$->itServerType, $7);
  397.     $$->itServerType = $7;
  398. }
  399.             |    TransTypeSpec syOutTran syColon syIdentifier
  400.                 syIdentifier syLParen syIdentifier syRParen
  401. {
  402.     $$ = $1;
  403.  
  404.     if (($$->itServerType != strNULL) && !streql($$->itServerType, $4))
  405.     warn("conflicting server types (%s, %s)",
  406.          $$->itServerType, $4);
  407.     $$->itServerType = $4;
  408.  
  409.     if (($$->itOutTrans != strNULL) && !streql($$->itOutTrans, $5))
  410.     warn("conflicting out-translation functions (%s, %s)",
  411.          $$->itOutTrans, $5);
  412.     $$->itOutTrans = $5;
  413.  
  414.     if (($$->itTransType != strNULL) && !streql($$->itTransType, $7))
  415.     warn("conflicting translation types (%s, %s)",
  416.          $$->itTransType, $7);
  417.     $$->itTransType = $7;
  418. }
  419.             |    TransTypeSpec syDestructor syColon syIdentifier
  420.                 syLParen syIdentifier syRParen
  421. {
  422.     $$ = $1;
  423.  
  424.     if (($$->itDestructor != strNULL) && !streql($$->itDestructor, $4))
  425.     warn("conflicting destructor functions (%s, %s)",
  426.          $$->itDestructor, $4);
  427.     $$->itDestructor = $4;
  428.  
  429.     if (($$->itTransType != strNULL) && !streql($$->itTransType, $6))
  430.     warn("conflicting translation types (%s, %s)",
  431.          $$->itTransType, $6);
  432.     $$->itTransType = $6;
  433. }
  434.             |    TransTypeSpec syCType syColon syIdentifier
  435. {
  436.     $$ = $1;
  437.  
  438.     if (($$->itUserType != strNULL) && !streql($$->itUserType, $4))
  439.     warn("conflicting user types (%s, %s)",
  440.          $$->itUserType, $4);
  441.     $$->itUserType = $4;
  442.  
  443.     if (($$->itServerType != strNULL) && !streql($$->itServerType, $4))
  444.     warn("conflicting server types (%s, %s)",
  445.          $$->itServerType, $4);
  446.     $$->itServerType = $4;
  447. }
  448.             |    TransTypeSpec syCUserType syColon syIdentifier
  449. {
  450.     $$ = $1;
  451.  
  452.     if (($$->itUserType != strNULL) && !streql($$->itUserType, $4))
  453.     warn("conflicting user types (%s, %s)",
  454.          $$->itUserType, $4);
  455.     $$->itUserType = $4;
  456. }
  457.             |    TransTypeSpec syCServerType
  458.                 syColon syIdentifier
  459. {
  460.     $$ = $1;
  461.  
  462.     if (($$->itServerType != strNULL) && !streql($$->itServerType, $4))
  463.     warn("conflicting server types (%s, %s)",
  464.          $$->itServerType, $4);
  465.     $$->itServerType = $4;
  466. }
  467.             ;
  468.  
  469. TypeSpec        :    BasicTypeSpec
  470.                 { $$ = $1; }
  471.             |    PrevTypeSpec
  472.                 { $$ = $1; }
  473.             |    VarArrayHead TypeSpec
  474.                 { $$ = itVarArrayDecl($1, $2); }
  475.             |    ArrayHead TypeSpec
  476.                 { $$ = itArrayDecl($1, $2); }
  477.             |    syCaret TypeSpec
  478.                 { $$ = itPtrDecl($2); }
  479.             |    StructHead TypeSpec
  480.                 { $$ = itStructDecl($1, $2); }
  481.             |    CStringSpec
  482.                 { $$ = $1; }
  483.             ;
  484.  
  485. BasicTypeSpec        :    IPCType
  486. {
  487.     $$ = itShortDecl($1.innumber, $1.instr,
  488.              $1.outnumber, $1.outstr,
  489.              $1.size);
  490. }
  491.             |    syLParen IPCType syComma IntExp
  492.                 IPCFlags syRParen
  493. {
  494.     $$ = itLongDecl($2.innumber, $2.instr,
  495.             $2.outnumber, $2.outstr,
  496.             $2.size, $4, $5);
  497. }
  498.             ;
  499.  
  500. IPCFlags        :    /* empty */
  501.                 { $$ = flNone; }
  502.             |    IPCFlags syComma syIPCFlag
  503. {
  504.     if ($1 & $3)
  505.     warn("redundant IPC flag ignored");
  506.     else
  507.     $$ = $1 | $3;
  508. }
  509.             |    IPCFlags syComma syIPCFlag syLBrack syRBrack
  510. {
  511.     if ($3 != flDealloc)
  512.     warn("only Dealloc is variable");
  513.     else
  514.     $$ = $1 | flMaybeDealloc;
  515. }
  516.             ;
  517.  
  518. PrimIPCType        :    syNumber
  519. {
  520.     $$.innumber = $$.outnumber = $1;
  521.     $$.instr = $$.outstr = strNULL;
  522.     $$.size = 0;
  523. }
  524.             |    sySymbolicType
  525.                 { $$ = $1; }
  526.             ;
  527.  
  528. IPCType            :    PrimIPCType
  529.                 { $$ = $1; }
  530.             |    PrimIPCType syBar PrimIPCType
  531. {
  532.     if ($1.size != $3.size)
  533.     {
  534.     if ($1.size == 0)
  535.         $$.size = $3.size;
  536.     else if ($3.size == 0)
  537.         $$.size = $1.size;
  538.     else
  539.     {
  540.         error("sizes in IPCTypes (%d, %d) aren't equal",
  541.           $1.size, $3.size);
  542.         $$.size = 0;
  543.     }
  544.     }
  545.     else
  546.     $$.size = $1.size;
  547.     $$.innumber = $1.innumber;
  548.     $$.instr = $1.instr;
  549.     $$.outnumber = $3.outnumber;
  550.     $$.outstr = $3.outstr;
  551. }
  552.             ;
  553.  
  554. PrevTypeSpec        :    syIdentifier
  555.                 { $$ = itPrevDecl($1); }
  556.             ;
  557.  
  558. VarArrayHead        :    syArray syLBrack syRBrack syOf
  559.                 { $$ = 0; }
  560.             |    syArray syLBrack syStar syRBrack syOf
  561.                 { $$ = 0; }
  562.             |    syArray syLBrack syStar syColon IntExp 
  563.                 syRBrack syOf
  564.                 { $$ = $5; }
  565.             ;
  566.  
  567. ArrayHead        :    syArray syLBrack IntExp syRBrack syOf
  568.                 { $$ = $3; }
  569.             ;
  570.  
  571. StructHead        :    syStruct syLBrack IntExp syRBrack syOf
  572.                 { $$ = $3; }
  573.             ;
  574.  
  575. CStringSpec        :    syCString syLBrack IntExp syRBrack
  576.                 { $$ = itCStringDecl($3, FALSE); }
  577.             |    syCString syLBrack syStar syColon
  578.                 IntExp syRBrack
  579.                 { $$ = itCStringDecl($5, TRUE); }
  580.             ;
  581.  
  582. IntExp            :     IntExp    syPlus    IntExp
  583.                 { $$ = $1 + $3;    }
  584.             |     IntExp    syMinus    IntExp
  585.                 { $$ = $1 - $3;    }
  586.             |    IntExp    syStar    IntExp
  587.                 { $$ = $1 * $3;    }
  588.             |     IntExp    syDiv    IntExp
  589.                 { $$ = $1 / $3;    }
  590.             |    syNumber
  591.                 { $$ = $1;    }
  592.             |    syLParen IntExp syRParen
  593.                 { $$ = $2;    }
  594.             ;
  595.  
  596.  
  597. RoutineDecl        :    Routine            { $$ = $1; }
  598.             |    SimpleRoutine        { $$ = $1; }
  599.             |    Procedure        { $$ = $1; }
  600.             |    SimpleProcedure        { $$ = $1; }
  601.             |    Function        { $$ = $1; }
  602.             ;
  603.  
  604. Routine            :    syRoutine syIdentifier Arguments
  605.                 { $$ = rtMakeRoutine($2, $3); }
  606.             ;
  607.  
  608. SimpleRoutine        :    sySimpleRoutine syIdentifier Arguments
  609.                 { $$ = rtMakeSimpleRoutine($2, $3); }
  610.             ;
  611.  
  612. Procedure        :    syProcedure syIdentifier Arguments
  613.                 { $$ = rtMakeProcedure($2, $3); }
  614.             ;
  615.  
  616. SimpleProcedure        :    sySimpleProcedure syIdentifier Arguments
  617.                 { $$ = rtMakeSimpleProcedure($2, $3); }
  618.             ;
  619.  
  620. Function        :    syFunction syIdentifier Arguments ArgumentType
  621.                 { $$ = rtMakeFunction($2, $3, $4); }
  622.             ;
  623.  
  624. Arguments        :    syLParen syRParen
  625.                 { $$ = argNULL; }
  626.             |    syLParen ArgumentList syRParen
  627.                 { $$ = $2; }
  628.  
  629.             ;
  630.  
  631. ArgumentList        :    Argument
  632.                 { $$ = $1; }
  633.             |    Argument sySemi ArgumentList
  634. {
  635.     $$ = $1;
  636.     $$->argNext = $3;
  637. }
  638.             ;
  639.  
  640. Argument        :    Direction syIdentifier ArgumentType IPCFlags
  641. {
  642.     $$ = argAlloc();
  643.     $$->argKind = $1;
  644.     $$->argName = $2;
  645.     $$->argType = $3;
  646.     $$->argFlags = $4;
  647. }
  648.             ;
  649.  
  650. Direction        :    /* empty */    { $$ = akNone; }
  651.             |    syIn        { $$ = akIn; }
  652.             |    syOut        { $$ = akOut; }
  653.             |    syInOut        { $$ = akInOut; }
  654.             |    syRequestPort    { $$ = akRequestPort; }
  655.             |    syReplyPort    { $$ = akReplyPort; }
  656.             |    sySReplyPort    { $$ = akSReplyPort; }
  657.             |    syUReplyPort    { $$ = akUReplyPort; }
  658.             |    syWaitTime    { $$ = akWaitTime; }
  659.             |    syMsgOption    { $$ = akMsgOption; }
  660.             |    syMsgSeqno    { $$ = akMsgSeqno; }
  661.             ;
  662.  
  663. ArgumentType        :    syColon syIdentifier
  664. {
  665.     $$ = itLookUp($2);
  666.     if ($$ == itNULL)
  667.     error("type '%s' not defined", $2);
  668. }
  669.             |    syColon NamedTypeSpec
  670.                 { $$ = $2; }
  671.             ;
  672.  
  673. LookString        :    /* empty */
  674.                 { LookString(); }
  675.             ;
  676.  
  677. LookFileName        :    /* empty */
  678.                 { LookFileName(); }
  679.             ;
  680.  
  681. LookQString        :    /* empty */
  682.                 { LookQString(); }
  683.             ;
  684.  
  685. %%
  686.  
  687. yyerror(s)
  688.     char *s;
  689. {
  690.     error(s);
  691. }
  692.  
  693. static char *
  694. import_name(sk)
  695.     statement_kind_t sk;
  696. {
  697.     switch (sk)
  698.     {
  699.       case skImport:
  700.     return "Import";
  701.       case skSImport:
  702.     return "SImport";
  703.       case skUImport:
  704.     return "UImport";
  705.       default:
  706.     fatal("import_name(%d): not import statement", (int) sk);
  707.     /*NOTREACHED*/
  708.     }
  709. }
  710.